<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Example: Adding New Object Members During Parsing</title>
    <link rel="stylesheet" href="http://yui.yahooapis.com/3.4.0pr3/build/cssgrids/grids-min.css">
    <link rel="stylesheet" href="../assets/css/main.css">
    <link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
    <script src="../../build/yui/yui-min.js"></script>
</head>
<body>

<div id="doc">
    <h1>Example: Adding New Object Members During Parsing</h1>

    

    <div class="yui3-g">
        <div id="main" class="yui3-u">
            <div class="content"><div class="intro">
<p>
    This example shows how to use the <code>reviver</code> parameter in <code>JSON.parse()</code> to add new object members and format existing members during the parsing phase.
</p>
</div>

<div class="example yui3-skin-sam">
    <div id="demo">
    <p>Choose a currency, then get the data</p>
    <select>
        <option value="ARS">Argentine Peso</option>
        <option value="AUD">Australian Dollar</option>
        <option value="BRL">Brazilian Real</option>
        <option value="GBP">British Pound</option>
        <option value="CAD">Canadian Dollar</option>
        <option value="CNY">Chinese Yuan</option>
        <option value="COP">Colombian Peso</option>
        <option value="HRK">Croatian Kuna</option>
        <option value="CZK">Czech Koruna</option>
        <option value="DKK">Danish Krone</option>
        <option value="EEK">Estonian Kroon</option>
        <option value="EUR">Euro</option>
        <option value="HKD">Hong Kong Dollar</option>
        <option value="HUF">Hungarian Forint</option>
        <option value="ISK">Iceland Krona</option>
        <option value="INR">Indian Rupee</option>
        <option value="JPY">Japanese Yen</option>
        <option value="KRW">Korean Won</option>
        <option value="LVL">Latvian Lat</option>
        <option value="LTL">Lithuanian Lita</option>
        <option value="MYR">Malaysian Ringgit</option>
        <option value="MXN">Mexican Peso</option>
        <option value="NZD">New Zealand Dollar</option>
        <option value="NOK">Norwegian Krone</option>
        <option value="PHP">Philippine Peso</option>
        <option value="PLN">Polish Zloty</option>
        <option value="RUB">Russian Rouble</option>
        <option value="SGD">Singapore Dollar</option>
        <option value="SKK">Slovak Koruna</option>
        <option value="ZAR">South African Rand</option>
        <option value="LKR">Sri Lanka Rupee</option>
        <option value="SEK">Swedish Krona</option>
        <option value="TRY">Turkey Lira</option>
        <option value="USD" selected="selected">U.S. Dollar</option>
        <option value="CHF">Swiss Franc</option>
        <option value="TWD">Taiwan Dollar</option>
        <option value="THB">Thai Baht</option>
    </select>
    <input type="button" id="demo_go" value="Get Data">

    <table cellspacing="0">
    <caption>Inventory</caption>
    <thead>
        <tr>
            <th>SKU</th>
            <th>Item</th>
            <th>Price (USD)</th>
            <th>Price (<span>USD</span>)</th>
        </tr>
    </thead>
    <tbody>
        <tr><td colspan="4">Click <em>Get Data</em></td></tr>
    </tbody>
    </table>
</div>

<script>
YUI().use("node", "io", "json-parse",function (Y) {

// Safari 4.0.3's native JSON does not support adding members during parse,
// so use JavaScript implementation for consistency
Y.JSON.useNativeParse = false;

var example = {
    rates : {"USD":1,"EUR":0.6661,"GBP":0.5207,"AUD":1.1225,"BRL":1.609,"NZD":1.4198,"CAD":1.0667,"CHF":1.0792,"CNY":6.8587 ,"DKK":4.9702,"HKD":7.8064,"INR":42.0168,"JPY":109.8901,"KRW":1000,"LKR":107.5269,"MXN":10.1317,"MYR" :3.3167,"NOK":5.3277,"SEK":6.2617,"SGD":1.4073,"THB":33.7838,"TWD":31.1526,"VEF":2.1445,"ZAR":7.6923 ,"BGN":1.3028,"CZK":16.0514,"EEK":10.4275,"HUF":158.7302,"LTL":2.2999,"LVL":0.4692,"PLN":2.1758,"RON" :2.3804,"SKK":20.2429,"ISK":4.8008,"HRK":81.3008,"RUB":24.3309,"TRY":1.1811,"PHP":44.2478,"COP":2000 ,"ARS":3.1289},

    currency : 'USD',

    convert : function (k,v) {
        // 'this' will refer to the object containing the key:value pair,
        // so this step will add a new object member while leaving the original
        // intact (but formatted to two decimal places).  If the original
        // is not needed, just return the converted value.
        if (k === 'Price') {
            var x = Math.round(v * example.rates[example.currency] * 100) / 100;
            this.convertedPrice = x.toFixed(2); // added to item
            return v.toFixed(2); // assigned to item.Price
        }
        return v;
    },

    updateTable : function (inventory) {
        // Update the column header
        Y.one('#demo table th span').set('innerHTML',example.currency);

        var tbody = Y.one('#demo table tbody'),
            html  = ['<table><tbody>'],
            rowTemplate = '<tr><td>{SKU}</td><td>{Item}</td><td>{Price}</td><td>{convertedPrice}</td></tr>',
            i, len;

        if (inventory) {
            for (i = 0, len = inventory.length; i < len; ++i) {
                html.push(Y.Lang.sub(rowTemplate, inventory[i]));
            }
        } else {
            html.push('<tr><td colspan="4">No Inventory data</td></tr>');
        }

        html.push('</tbody></table>');

        tbody.replace(Y.Node.create(html.join('')).one('tbody'));
    }
};

Y.one('#demo_go').on('click', function (e) {
    // Disable the button temporarily
    this.set('disabled',true);

    // Store the requested currency
    var sel = Y.one("#demo select");
    example.currency = sel.get("options").item(sel.get("selectedIndex")).get("value");

    Y.io('../assets/json/json-convert-values-response.json',{
        timeout : 3000,
        on : {
            success : function (xid, res) {
                var inventory;
                try {
                    inventory = Y.JSON.parse(res.responseText,example.convert);

                    example.updateTable(inventory);
                }
                catch(e) {
                    alert("Error getting inventory data");
                }
                finally {
                    Y.one('#demo_go').set('disabled',false);
                }
            },
            failure : function () {
                alert("Error getting inventory data");
            }
        }
    });
});

// Expose example objects for inspection
YUI.example = example;
});
</script>

</div>

<h2>The Data</h2>
<p>
    The data returned from the server will be a JSON string containing this object structure:
</p>

<pre class="code prettyprint">[
    {&quot;SKU&quot;:&quot;23-23874&quot;, &quot;Price&quot;:23.99,  &quot;Item&quot;:&quot;Helmet&quot;},
    {&quot;SKU&quot;:&quot;48-38835&quot;, &quot;Price&quot;:14.97,  &quot;Item&quot;:&quot;Football&quot;},
    {&quot;SKU&quot;:&quot;84-84848&quot;, &quot;Price&quot;:3.49,   &quot;Item&quot;:&quot;Goggles&quot;},
    {&quot;SKU&quot;:&quot;84-84843&quot;, &quot;Price&quot;:183,    &quot;Item&quot;:&quot;Badminton Set&quot;},
    {&quot;SKU&quot;:&quot;84-39321&quot;, &quot;Price&quot;:6.79,   &quot;Item&quot;:&quot;Tennis Balls&quot;},
    {&quot;SKU&quot;:&quot;39-48949&quot;, &quot;Price&quot;:618,    &quot;Item&quot;:&quot;Snowboard&quot;},
    {&quot;SKU&quot;:&quot;99-28128&quot;, &quot;Price&quot;:78.99,  &quot;Item&quot;:&quot;Cleats&quot;},
    {&quot;SKU&quot;:&quot;83-48281&quot;, &quot;Price&quot;:4.69,   &quot;Item&quot;:&quot;Volleyball&quot;},
    {&quot;SKU&quot;:&quot;89-32811&quot;, &quot;Price&quot;:0.59,   &quot;Item&quot;:&quot;Sweatband&quot;},
    {&quot;SKU&quot;:&quot;28-22847&quot;, &quot;Price&quot;:779.98, &quot;Item&quot;:&quot;Golf Set&quot;},
    {&quot;SKU&quot;:&quot;38-38281&quot;, &quot;Price&quot;:8.25,   &quot;Item&quot;:&quot;Basketball Shorts&quot;},
    {&quot;SKU&quot;:&quot;82-38333&quot;, &quot;Price&quot;:1.39,   &quot;Item&quot;:&quot;Lip balm&quot;},
    {&quot;SKU&quot;:&quot;21-38485&quot;, &quot;Price&quot;:0.07,   &quot;Item&quot;:&quot;Ping Pong ball&quot;},
    {&quot;SKU&quot;:&quot;83-38285&quot;, &quot;Price&quot;:3.99,   &quot;Item&quot;:&quot;Hockey Puck&quot;}
]</pre>


<h2>Create a <code>reviver</code> function</h2>
<p>
    We'll contain all the moving parts in an <code>example</code> namespace. In it, we'll include the currency exchange rates and a function to reference the rates to add a new member to the JSON response as it is being parsed.
</p>

<pre class="code prettyprint">YUI().use(&quot;node&quot;, &quot;io&quot;, &quot;json-parse&quot;,function (Y) {

var example = {
    rates : {&quot;USD&quot;:1,&quot;EUR&quot;:0.6661,...,&quot;COP&quot;:2000 ,&quot;ARS&quot;:3.1289},

    currency : &#x27;USD&#x27;, &#x2F;&#x2F; updated by the select element

    convert : function (k,v) {
        &#x2F;&#x2F; &#x27;this&#x27; will refer to the object containing the key:value pair,
        &#x2F;&#x2F; so this step will add a new object member while leaving the original
        &#x2F;&#x2F; intact (but formatted to two decimal places).  If the original
        &#x2F;&#x2F; is not needed, just return the converted value.
        if (k === &#x27;Price&#x27;) {
            var x = Math.round(v * example.rates[example.currency] * 100) &#x2F; 100;
            this.convertedPrice = x.toFixed(2); &#x2F;&#x2F; added to item
            return v.toFixed(2); &#x2F;&#x2F; assigned to item.Price
        }
        return v;
    },
    …
};
…</pre>


<h2>Sending the request and parsing the JSON response</h2>
<p>
    When the <em>Get Data</em> button is clicked, we send an io request for the JSON data, and in our <code>success</code> handler, pass our conversion function to <code>JSON.parse()</code> with the response text. The resulting inventory records will have an additional member, <code>convertedPrice</code>. This data is then passed to a UI method to update the inventory table.
</p>

<pre class="code prettyprint">Y.one(&#x27;#demo_go&#x27;).on(&#x27;click&#x27;, function (e) {
    &#x2F;&#x2F; Disable the button temporarily
    this.set(&#x27;disabled&#x27;,true);

    &#x2F;&#x2F; Store the requested currency
    var sel = Y.one(&quot;#demo select&quot;);
    example.currency = sel.get(&quot;options&quot;).item(sel.get(&quot;selectedIndex&quot;)).get(&quot;value&quot;);

    &#x2F;&#x2F; Send the request for the JSON data
    Y.io(&#x27;..&#x2F;assets&#x2F;json&#x2F;json-convert-values-response.json&#x27;,{
        timeout : 3000,
        on : {
            success : function (xid, res) {
                var inventory;
                try {
                    inventory = Y.JSON.parse(res.responseText,example.convert);

                    example.updateTable(inventory);
                }
                catch(e) {
                    alert(&quot;Error getting inventory data&quot;);
                }
                finally {
                    Y.one(&#x27;#demo_go&#x27;).set(&#x27;disabled&#x27;,false);
                }
            },
            failure : function () {
                alert(&quot;Error getting inventory data&quot;);
            }
        }
    });
});

}); &#x2F;&#x2F; End YUI(..).use(..,function (Y) {</pre>


<h2>Complete Example Source</h2>

<pre class="code prettyprint">&lt;div id=&quot;demo&quot;&gt;
    &lt;p&gt;Choose a currency, then get the data&lt;&#x2F;p&gt;
    &lt;select&gt;
        &lt;option value=&quot;ARS&quot;&gt;Argentine Peso&lt;&#x2F;option&gt;
        &lt;option value=&quot;AUD&quot;&gt;Australian Dollar&lt;&#x2F;option&gt;
        &lt;option value=&quot;BRL&quot;&gt;Brazilian Real&lt;&#x2F;option&gt;
        &lt;option value=&quot;GBP&quot;&gt;British Pound&lt;&#x2F;option&gt;
        &lt;option value=&quot;CAD&quot;&gt;Canadian Dollar&lt;&#x2F;option&gt;
        &lt;option value=&quot;CNY&quot;&gt;Chinese Yuan&lt;&#x2F;option&gt;
        &lt;option value=&quot;COP&quot;&gt;Colombian Peso&lt;&#x2F;option&gt;
        &lt;option value=&quot;HRK&quot;&gt;Croatian Kuna&lt;&#x2F;option&gt;
        &lt;option value=&quot;CZK&quot;&gt;Czech Koruna&lt;&#x2F;option&gt;
        &lt;option value=&quot;DKK&quot;&gt;Danish Krone&lt;&#x2F;option&gt;
        &lt;option value=&quot;EEK&quot;&gt;Estonian Kroon&lt;&#x2F;option&gt;
        &lt;option value=&quot;EUR&quot;&gt;Euro&lt;&#x2F;option&gt;
        &lt;option value=&quot;HKD&quot;&gt;Hong Kong Dollar&lt;&#x2F;option&gt;
        &lt;option value=&quot;HUF&quot;&gt;Hungarian Forint&lt;&#x2F;option&gt;
        &lt;option value=&quot;ISK&quot;&gt;Iceland Krona&lt;&#x2F;option&gt;
        &lt;option value=&quot;INR&quot;&gt;Indian Rupee&lt;&#x2F;option&gt;
        &lt;option value=&quot;JPY&quot;&gt;Japanese Yen&lt;&#x2F;option&gt;
        &lt;option value=&quot;KRW&quot;&gt;Korean Won&lt;&#x2F;option&gt;
        &lt;option value=&quot;LVL&quot;&gt;Latvian Lat&lt;&#x2F;option&gt;
        &lt;option value=&quot;LTL&quot;&gt;Lithuanian Lita&lt;&#x2F;option&gt;
        &lt;option value=&quot;MYR&quot;&gt;Malaysian Ringgit&lt;&#x2F;option&gt;
        &lt;option value=&quot;MXN&quot;&gt;Mexican Peso&lt;&#x2F;option&gt;
        &lt;option value=&quot;NZD&quot;&gt;New Zealand Dollar&lt;&#x2F;option&gt;
        &lt;option value=&quot;NOK&quot;&gt;Norwegian Krone&lt;&#x2F;option&gt;
        &lt;option value=&quot;PHP&quot;&gt;Philippine Peso&lt;&#x2F;option&gt;
        &lt;option value=&quot;PLN&quot;&gt;Polish Zloty&lt;&#x2F;option&gt;
        &lt;option value=&quot;RUB&quot;&gt;Russian Rouble&lt;&#x2F;option&gt;
        &lt;option value=&quot;SGD&quot;&gt;Singapore Dollar&lt;&#x2F;option&gt;
        &lt;option value=&quot;SKK&quot;&gt;Slovak Koruna&lt;&#x2F;option&gt;
        &lt;option value=&quot;ZAR&quot;&gt;South African Rand&lt;&#x2F;option&gt;
        &lt;option value=&quot;LKR&quot;&gt;Sri Lanka Rupee&lt;&#x2F;option&gt;
        &lt;option value=&quot;SEK&quot;&gt;Swedish Krona&lt;&#x2F;option&gt;
        &lt;option value=&quot;TRY&quot;&gt;Turkey Lira&lt;&#x2F;option&gt;
        &lt;option value=&quot;USD&quot; selected=&quot;selected&quot;&gt;U.S. Dollar&lt;&#x2F;option&gt;
        &lt;option value=&quot;CHF&quot;&gt;Swiss Franc&lt;&#x2F;option&gt;
        &lt;option value=&quot;TWD&quot;&gt;Taiwan Dollar&lt;&#x2F;option&gt;
        &lt;option value=&quot;THB&quot;&gt;Thai Baht&lt;&#x2F;option&gt;
    &lt;&#x2F;select&gt;
    &lt;input type=&quot;button&quot; id=&quot;demo_go&quot; value=&quot;Get Data&quot;&gt;

    &lt;table cellspacing=&quot;0&quot;&gt;
    &lt;caption&gt;Inventory&lt;&#x2F;caption&gt;
    &lt;thead&gt;
        &lt;tr&gt;
            &lt;th&gt;SKU&lt;&#x2F;th&gt;
            &lt;th&gt;Item&lt;&#x2F;th&gt;
            &lt;th&gt;Price (USD)&lt;&#x2F;th&gt;
            &lt;th&gt;Price (&lt;span&gt;USD&lt;&#x2F;span&gt;)&lt;&#x2F;th&gt;
        &lt;&#x2F;tr&gt;
    &lt;&#x2F;thead&gt;
    &lt;tbody&gt;
        &lt;tr&gt;&lt;td colspan=&quot;4&quot;&gt;Click &lt;em&gt;Get Data&lt;&#x2F;em&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
    &lt;&#x2F;tbody&gt;
    &lt;&#x2F;table&gt;
&lt;&#x2F;div&gt;

&lt;script&gt;
YUI().use(&quot;node&quot;, &quot;io&quot;, &quot;json-parse&quot;,function (Y) {

&#x2F;&#x2F; Safari 4.0.3&#x27;s native JSON does not support adding members during parse,
&#x2F;&#x2F; so use JavaScript implementation for consistency
Y.JSON.useNativeParse = false;

var example = {
    rates : {&quot;USD&quot;:1,&quot;EUR&quot;:0.6661,&quot;GBP&quot;:0.5207,&quot;AUD&quot;:1.1225,&quot;BRL&quot;:1.609,&quot;NZD&quot;:1.4198,&quot;CAD&quot;:1.0667,&quot;CHF&quot;:1.0792,&quot;CNY&quot;:6.8587 ,&quot;DKK&quot;:4.9702,&quot;HKD&quot;:7.8064,&quot;INR&quot;:42.0168,&quot;JPY&quot;:109.8901,&quot;KRW&quot;:1000,&quot;LKR&quot;:107.5269,&quot;MXN&quot;:10.1317,&quot;MYR&quot; :3.3167,&quot;NOK&quot;:5.3277,&quot;SEK&quot;:6.2617,&quot;SGD&quot;:1.4073,&quot;THB&quot;:33.7838,&quot;TWD&quot;:31.1526,&quot;VEF&quot;:2.1445,&quot;ZAR&quot;:7.6923 ,&quot;BGN&quot;:1.3028,&quot;CZK&quot;:16.0514,&quot;EEK&quot;:10.4275,&quot;HUF&quot;:158.7302,&quot;LTL&quot;:2.2999,&quot;LVL&quot;:0.4692,&quot;PLN&quot;:2.1758,&quot;RON&quot; :2.3804,&quot;SKK&quot;:20.2429,&quot;ISK&quot;:4.8008,&quot;HRK&quot;:81.3008,&quot;RUB&quot;:24.3309,&quot;TRY&quot;:1.1811,&quot;PHP&quot;:44.2478,&quot;COP&quot;:2000 ,&quot;ARS&quot;:3.1289},

    currency : &#x27;USD&#x27;,

    convert : function (k,v) {
        &#x2F;&#x2F; &#x27;this&#x27; will refer to the object containing the key:value pair,
        &#x2F;&#x2F; so this step will add a new object member while leaving the original
        &#x2F;&#x2F; intact (but formatted to two decimal places).  If the original
        &#x2F;&#x2F; is not needed, just return the converted value.
        if (k === &#x27;Price&#x27;) {
            var x = Math.round(v * example.rates[example.currency] * 100) &#x2F; 100;
            this.convertedPrice = x.toFixed(2); &#x2F;&#x2F; added to item
            return v.toFixed(2); &#x2F;&#x2F; assigned to item.Price
        }
        return v;
    },

    updateTable : function (inventory) {
        &#x2F;&#x2F; Update the column header
        Y.one(&#x27;#demo table th span&#x27;).set(&#x27;innerHTML&#x27;,example.currency);

        var tbody = Y.one(&#x27;#demo table tbody&#x27;),
            html  = [&#x27;&lt;table&gt;&lt;tbody&gt;&#x27;],
            rowTemplate = &#x27;&lt;tr&gt;&lt;td&gt;{SKU}&lt;&#x2F;td&gt;&lt;td&gt;{Item}&lt;&#x2F;td&gt;&lt;td&gt;{Price}&lt;&#x2F;td&gt;&lt;td&gt;{convertedPrice}&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&#x27;,
            i, len;

        if (inventory) {
            for (i = 0, len = inventory.length; i &lt; len; ++i) {
                html.push(Y.Lang.sub(rowTemplate, inventory[i]));
            }
        } else {
            html.push(&#x27;&lt;tr&gt;&lt;td colspan=&quot;4&quot;&gt;No Inventory data&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;&#x27;);
        }

        html.push(&#x27;&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;&#x27;);

        tbody.replace(Y.Node.create(html.join(&#x27;&#x27;)).one(&#x27;tbody&#x27;));
    }
};

Y.one(&#x27;#demo_go&#x27;).on(&#x27;click&#x27;, function (e) {
    &#x2F;&#x2F; Disable the button temporarily
    this.set(&#x27;disabled&#x27;,true);

    &#x2F;&#x2F; Store the requested currency
    var sel = Y.one(&quot;#demo select&quot;);
    example.currency = sel.get(&quot;options&quot;).item(sel.get(&quot;selectedIndex&quot;)).get(&quot;value&quot;);

    Y.io(&#x27;..&#x2F;assets&#x2F;json&#x2F;json-convert-values-response.json&#x27;,{
        timeout : 3000,
        on : {
            success : function (xid, res) {
                var inventory;
                try {
                    inventory = Y.JSON.parse(res.responseText,example.convert);

                    example.updateTable(inventory);
                }
                catch(e) {
                    alert(&quot;Error getting inventory data&quot;);
                }
                finally {
                    Y.one(&#x27;#demo_go&#x27;).set(&#x27;disabled&#x27;,false);
                }
            },
            failure : function () {
                alert(&quot;Error getting inventory data&quot;);
            }
        }
    });
});

&#x2F;&#x2F; Expose example objects for inspection
YUI.example = example;
});
&lt;&#x2F;script&gt;</pre>

</div>
        </div>

        <div id="sidebar" class="yui3-u">
            

            
                <div class="sidebox">
                    <div class="hd">
                        <h2 class="no-toc">Examples</h2>
                    </div>

                    <div class="bd">
                        <ul class="examples">
                            
                                
                                    <li data-description="Use JSON to parse data received via XMLHttpRequest via Y.io calls — a simple JSON use case.">
                                        <a href="json-connect.html">JSON with Y.io</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Use the replacer and reviver parameters to reconstitute object instances that have been serialized to JSON.">
                                        <a href="json-freeze-thaw.html">Rebuilding Class Instances from JSON Data</a>
                                    </li>
                                
                            
                                
                                    <li data-description="Use a currency conversion calculation to add a new price member to a JSON response, demonstrating how JSON data, once retrieved, can be transformed during parsing.">
                                        <a href="json-convert-values.html">Adding New Object Members During Parsing</a>
                                    </li>
                                
                            
                                
                            
                        </ul>
                    </div>
                </div>
            

            
                <div class="sidebox">
                    <div class="hd">
                        <h2 class="no-toc">Examples That Use This Component</h2>
                    </div>

                    <div class="bd">
                        <ul class="examples">
                            
                                
                            
                                
                            
                                
                            
                                
                                    <li data-description="Portal style example using Drag &amp; Drop Event Bubbling and Animation.">
                                        <a href="../dd/portal-drag.html">Portal Style Example</a>
                                    </li>
                                
                            
                        </ul>
                    </div>
                </div>
            
        </div>
    </div>
</div>

<script src="../assets/vendor/prettify/prettify-min.js"></script>
<script>prettyPrint();</script>

</body>
</html>
